package jobManagement.impl;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Calendar;

import org.globus.wsrf.Resource;
import org.globus.wsrf.ResourceIdentifier;
import org.globus.wsrf.ResourceLifetime;
import org.globus.wsrf.ResourceProperties;
import org.globus.wsrf.ResourceProperty;
import org.globus.wsrf.ResourcePropertySet;
import org.globus.wsrf.impl.ReflectionResourceProperty;
import org.globus.wsrf.impl.SimpleResourcePropertyMetaData;
import org.globus.wsrf.impl.SimpleResourcePropertySet;

public class JobManagementResource implements Resource, ResourceIdentifier,
		ResourceProperties, ResourceLifetime,PropertyChangeListener {

	/* Resource Property set */
	private ResourcePropertySet propSet;

	/* Resource key. This uniquely identifies this resource. */
	private Object key;

	/* Resource properties */
	private JobManager jobManager;
	private String jobStatus;
	private String oldStatus;
	private int jobManagerStatus;
	private Calendar terminationTime;

	/* Initializes RPs and returns a unique identifier for this resource */
	public Object initialize() throws Exception {
		this.key = new Integer(hashCode());
		this.propSet = new SimpleResourcePropertySet(
				JobManagementQNames.RESOURCE_PROPERTIES);

		try {
			ResourceProperty newStatus = new ReflectionResourceProperty(
					JobManagementQNames.RP_JOB_STATUS, "JobStatus", this);
			this.propSet.add(newStatus);
			
			ResourceProperty jobManagerStatus = new ReflectionResourceProperty(
					JobManagementQNames.RP_JOB_MANAGER_STATUS, "JobManagerStatus", this);
			this.propSet.add(jobManagerStatus);
						
			ResourceProperty termTimeRP = new ReflectionResourceProperty(
					SimpleResourcePropertyMetaData.TERMINATION_TIME, this);
			this.propSet.add(termTimeRP);

			ResourceProperty currTimeRP = new ReflectionResourceProperty(
					SimpleResourcePropertyMetaData.CURRENT_TIME, this);
			this.propSet.add(currTimeRP);
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}

		return key;
	}

	/* Get/Setters for the RPs */

	public int getJobManagerStatus() {
		if (jobManager == null) {
			this.jobManagerStatus = -1;
			return -1;
		}
		if (jobManager.getState().equals(Thread.State.NEW)) {
			this.jobManagerStatus = 0;
		}
		if (jobManager.getState().equals(Thread.State.RUNNABLE)) {
			this.jobManagerStatus = 1;
		}
		if (jobManager.getState().equals(Thread.State.BLOCKED)) {
			this.jobManagerStatus = 2;
		}
		if (jobManager.getState().equals(Thread.State.WAITING)) {
			this.jobManagerStatus = 3;
		}
		if (jobManager.getState().equals(Thread.State.TIMED_WAITING)) {
			this.jobManagerStatus = 4;
		}
		if (jobManager.getState().equals(Thread.State.TERMINATED)) {
			this.jobManagerStatus = 5;
		}
		return jobManagerStatus;
	}

	public void startJobManager(String proxy,String jobDescription) {
		if (getJobManagerStatus() == -1) {
			
			jobManager = new JobManager(proxy,jobDescription,0);
			jobManager.jobStatus.addPropertyChangeListener(this);
		}
		if (getJobManagerStatus()==0){
			jobManager.start();
		}
	}
	
	public void startJobManagerTimed(String proxy,String jobDescription,int counter) {
		if (getJobManagerStatus() == -1) {
			
			jobManager = new JobManager(proxy,jobDescription,counter);
			jobManager.jobStatus.addPropertyChangeListener(this);
		}
		if (getJobManagerStatus()==0){
			jobManager.start();
		}
	}
	
	public void stopJobManager() {
		if (jobManager != null) {
			jobManager.terminate();
			jobManager = null;
		}
	}

	/* Required by interface ResourceProperties */
	public ResourcePropertySet getResourcePropertySet() {
		return this.propSet;
	}

	/* Required by interface ResourceIdentifier */
	public Object getID() {
		return this.key;
	}

	/* Required by interface ResourceLifetime */
	public Calendar getCurrentTime() {
		return Calendar.getInstance();
	}

	public Calendar getTerminationTime() {
		return this.terminationTime;
	}

	public void setTerminationTime(Calendar terminationTime) {
		this.terminationTime = terminationTime;
	}

	public void propertyChange(PropertyChangeEvent evt) {
		setOldStatus((String) evt.getOldValue());
		setJobStatus((String) evt.getNewValue());

		System.out.println("[Listener] Job state changed from <<" + getOldStatus()
				+ ">> to <<" + getJobStatus() + ">>");
		
	}

	public void setOldStatus(String oldStatus) {
		this.oldStatus = oldStatus;
	}

	public String getOldStatus() {
		return oldStatus;
	}

	public void setJobStatus(String status) {
		this.jobStatus = status;
	}

	public String getJobStatus() {
		return jobStatus;
	}
}
